﻿Type.registerNamespace('TallComponents');

TallComponents.PdfViewerToolbar = function (element) {
    ///<summary>Toolbar for <see cref="T:J#TallComponents.PdfViewer"/> control.</summary>
    TallComponents.PdfViewerToolbar.initializeBase(this, [element]);
    this._targetControlId = null;
    this._targetControl;
    this._pageIndexSpan = null;
    this._buttons = Array();
    this._zoomSelect = null;
    this._zoomOptions = null;
    this._appLoadDelegate = null;
    this._busyIndicator = null;
    this._searchBox = null;
};

TallComponents.PdfViewerToolbar.prototype = {

   initialize: function () {
      ///<summary>Initializes the control.</summary>
      ///<remarks>The initialize method initializes the control and sets the base <see cref="M:J#Sys.Component.isInitialized"/> property to true.</remarks>
      TallComponents.PdfViewerToolbar.callBaseMethod(this, "initialize");
      this._buttons = [];

      var element = this.get_element();

      var links = element.getElementsByTagName('a');
      for (i = 0; i < links.length; i++) {
         if (links[i].id.length > 0) {
            this._buttons[links[i].id] = links[i];
         }
      }
      var select = element.getElementsByTagName('select');
      this._zoomSelect = select[0];
      this._zoomOptions = Array();
      for (i = 0; i < this._zoomSelect.options.length; i++) {
         this._zoomOptions.push({ value: this._zoomSelect.options[i].value, text: this._zoomSelect.options[i].text, disabled: this._zoomSelect.options[i].disabled });
      }

      var inputs = element.getElementsByTagName('input');
      if (inputs && inputs.length > 0) {
         this._searchBox = inputs[0];
         $addHandlers(this._searchBox, { keydown: this._onSeachBoxKeyDown }, this);
      }

      var images = element.getElementsByTagName('img');
      for (i = 0; i < images.length; i++) {
         if (images[i].id == 'busy') {
            this._busyIndicator = images[i];
            break;
         }
      }

      var divs = element.getElementsByTagName('div');
      for (i = 0; i < divs.length; i++) {
         if (divs[i].id == 'pageNumber') {
            this._pageIndexSpan = divs[i];
            break;
         }
      }

      if (this._zoomSelect) { $addHandlers(this._zoomSelect, { change: this._onZoomChanged }, this); }
      for (key in this._buttons) {
         $addHandlers(this._buttons[key], { click: this._onButtonClick }, this);
      }

      if (!this._hookupViewer()) {
         this._appLoadDelegate = Function.createDelegate(this, this._appLoad);
         Sys.Application.add_load(this._appLoadDelegate);
      }
   },

   dispose: function () {
      ///<summary>Removes the current control from the application.</summary>
      ///<remarks>The dispose method releases all resources from the <see cref="T:J#Sys.UI.Control"/> object, 
      ///unbinds it from its associated HTML Document Object Model (DOM) element, 
      ///and unregisters it from the application.</remarks>
      if (this._zoomSelect) { $clearHandlers(this._zoomSelect); }
      for (i = 0; i < this._buttons.length; i++) { if (this._buttons[i]) { $clearHandlers(this._buttons[i]); } }
      if (this._targetControl) {
         this._targetControl.remove_propertyChanged(this._onViewPropChanged);
         this._targetControl.remove_updating(this._onViewUpdating);
         this._targetControl.remove_updated(this._onViewUpdated);
         this._targetControl.remove_searching(this._onSearching);
         this._targetControl.remove_searchCompleted(this._onSearchCompleted);
      }
      if (this._searchBox) { $clearHandlers(this._searchBox); }
      if (this._appLoadDelegate) { Sys.Application.remove_load(this._appLoadDelegate); }

      TallComponents.PdfViewerToolbar.callBaseMethod(this, 'dispose');
   },

   _appLoad: function (sender, args) {
      Sys.Application.remove_load(this._appLoadDelegate);
      this._appLoadDelegate = null;
      this._hookupViewer();
   },

   _hookupViewer: function () {
      this._targetControl = $find(this._targetControlId);

      if (this._targetControl) {
         this._onViewUpdated(); // get initial state
         this._targetControl.add_propertyChanged(Function.createDelegate(this, this._onViewPropChanged));
         this._targetControl.add_updating(Function.createDelegate(this, this._onViewUpdating));
         this._targetControl.add_updated(Function.createDelegate(this, this._onViewUpdated));
         this._targetControl.add_searching(Function.createDelegate(this, this._onSearching));
         this._targetControl.add_searchCompleted(Function.createDelegate(this, this._onSearchCompleted));

         return true;
      }
      return false;
   },

   _onSeachBoxKeyDown: function (e) {
      // check for enter key
      if (e.keyCode == 13) {
         e.preventDefault();
         // fake search button click
         e.target = this._buttons['search'];
         this._onButtonClick(e);
      }
   },

   _onButtonClick: function (e) {
      e.preventDefault();

      var args = new Sys.EventArgs();
      args.target = e.target;
      while (args.target.id.length === 0) {
         if (!args.target.parentNode) {
            return;
         }
         args.target = args.target.parentNode;
      }
      args.command = args.target.id;
      args.suppressDefault = false;

      // #306 stop execution for disabled buttons
      if (Sys.UI.DomElement.containsCssClass(args.target, 'pdftbDisabled')) {
         return;
      }

      // dispatch event
      var h = this.get_events().getHandler('buttonClick');
      if (h) {
         try { h(this, args); }
         catch (ex) { }
      }

      if (!args.suppressDefault) {
         switch (args.command) {
            case 'prev':
               this._targetControl.previousPage();
               break;
            case 'next':
               this._targetControl.nextPage();
               break;
            case 'pan':
               this._targetControl.set_cursorMode('pan');
               break;
            case 'zoomIn':
               this._targetControl.set_cursorMode('zoomIn');
               break;
            case 'zoomOut':
               this._targetControl.set_cursorMode('zoomOut');
               break;
            case 'zoom1on1':
               this._targetControl.set_zoom(1);
               break;
            case 'zoomToPage':
               this._targetControl.set_zoom('page');
               break;
            case 'zoomToWidth':
               this._targetControl.set_zoom('width');
               break;
            case 'pageLayoutSingle':
               this._targetControl.set_pageLayout('single');
               break;
            case 'pageLayoutDouble':
               this._targetControl.set_pageLayout('double');
               break;
            case 'pageLayoutContinuous':
               this._targetControl.set_pageLayout('continuous');
               break;
            case 'pageLayoutContinuousDouble':
               this._targetControl.set_pageLayout('continuousdouble');
               break;
            case 'search':
               if (this._searchBox) {
                  var text = this._searchBox.value.trim();
                  if (text.length > 0) {
                     this._targetControl.search(this._searchBox.value, false, false);
                  }
               }
               break;
            case 'searchCancel':
               if (this._searchBox) {
                  this._targetControl.cancelSearch();
               }
               break;
            case 'rotateClockwise':
               this._targetControl.rotate('clockwise');
               break;
            case 'rotateCounterClockwise':
               this._targetControl.rotate('counterClockwise');
               break;
            default:
               break;
         }
      }
   },

   _onZoomChanged: function (e) {
      this._targetControl.set_zoom(this._zoomSelect.value);
   },

   _onViewPropChanged: function (sender, args) {
      if (args.get_propertyName() === "cursorMode") {
         this._updateToolbar();
      }
   },

   _onViewUpdating: function (sender, args) {
      this._busyIndicator.style.visibility = this._targetControl.get_isBusy() ? 'visible' : 'hidden';
   },

   _onViewUpdated: function (sender, args) {
      this._updateToolbar();

      var zoom = this._targetControl.get_zoom();
      var options = this._zoomSelect.options;
      var unknownZoomAdded = isNaN(zoom);
      this._zoomSelect.options.length = 0;
      for (i = 0; i < this._zoomOptions.length; i++) {
         if (isNaN(parseFloat(this._zoomOptions[i].value))) {
            var option = new Option(this._zoomOptions[i].text, this._zoomOptions[i].value, false, this._zoomOptions[i].value == zoom);
            if (this._zoomOptions[i].disabled) { option.disabled = true; }
            this._zoomSelect.options[this._zoomSelect.options.length] = option;
         }
         else {
            if (!unknownZoomAdded && zoom > this._zoomOptions[i].value) {
               this._zoomSelect.options[this._zoomSelect.options.length] = new Option(parseFloat(zoom * 100).toFixed(0) + "%", parseFloat(zoom).toFixed(0), false, true);
               unknownZoomAdded = true;
            }

            this._zoomSelect.options[this._zoomSelect.options.length] = new Option(this._zoomOptions[i].text, this._zoomOptions[i].value, false, zoom == this._zoomOptions[i].value);
         }
         if (this._zoomOptions[i].value == zoom) { unknownZoomAdded = true; }
      }
      if (!unknownZoomAdded) {
         this._zoomSelect.options[this._zoomSelect.options.length] = new Option(parseFloat(zoom * 100).toFixed(0) + "%", parseFloat(zoom).toFixed(0), false, true);
      }
   },

   _onSearching: function (sender, args) {
      this._setButtonState('search', false, false);
      this._setButtonState('searchCancel', true, false);
      this._zoomSelect.disabled = 'disabled';
   },
   _onSearchCompleted: function (sender, args) {
      this._setButtonState('search', true, false);
      this._setButtonState('searchCancel', false, false);
      this._zoomSelect.disabled = '';
   },

   _updateToolbar: function () {
      this._busyIndicator.style.visibility = this._targetControl.get_isBusy() ? 'visible' : 'hidden';

      var index = this._targetControl.get_pageIndex() + 1;

      var count = this._targetControl.get_pageCount();

      this._pageIndexSpan.innerHTML = (count > 0) ? index + " / " + count : "";

      this._setButtonState('prev', (count > 0 && index > 1), false);
      this._setButtonState('next', (count > 0 && index < count), false);

      var mode = this._targetControl.get_cursorMode();
      this._setButtonState('zoomIn', (count > 0), mode == 'zoomIn');
      this._setButtonState('zoomOut', (count > 0), mode == 'zoomOut');
      this._setButtonState('pan', (count > 0), mode == 'pan');

      this._zoomSelect.style.visibility = (count > 0) ? 'visible' : 'hidden';

      var zoom = this._targetControl.get_zoom();
      this._setButtonState('zoom1on1', (count > 0), zoom == 1);
      this._setButtonState('zoomToWidth', (count > 0), zoom == 'width');
      this._setButtonState('zoomToPage', (count > 0), zoom == 'page');

      var pageLayout = this._targetControl.get_pageLayout();
      this._setButtonState('pageLayoutSingle', (count > 0), pageLayout == 'single');
      this._setButtonState('pageLayoutDouble', (count > 0), pageLayout == 'double');
      this._setButtonState('pageLayoutContinuous', (count > 0), pageLayout == 'continuous');
      this._setButtonState('pageLayoutContinuousDouble', (count > 0), pageLayout == 'continuousdouble');

      this._setButtonState('open', true, false);
      this._setButtonState('close', (count > 0), false);

      var searchEnabled = this._targetControl.get_searchServiceUrl() && (count > 0);
      if (this._searchBox) {
         this._searchBox.disabled = searchEnabled ? '' : 'disabled';
      }
      this._setButtonState('search', searchEnabled, false);
      this._setButtonState('searchCancel', false, false);
      this._setButtonState('rotateClockwise', (count > 0), false);
      this._setButtonState('rotateCounterClockwise', (count > 0), false);
   },

   _setButtonState: function (buttonId, enabled, active) {
      this._toggleCssClass(this._buttons[buttonId], 'pdftbDisabled', !enabled);
      this._toggleCssClass(this._buttons[buttonId], 'pdftbActive', enabled && active);
   },

   _toggleCssClass: function (element, cssClass, add) {
      if (element) {
         var newClassName = '';
         var parts = element.className.split(' ');
         for (index = 0; index < parts.length; index++) {
            if (parts[index] == cssClass) {
               if (!add) { continue; } else { return; }
            }
            newClassName += ' ' + parts[index];
         }
         if (add) {
            newClassName += ' ' + cssClass;
         }
         element.className = newClassName;
      }
   },

   // Bind and unbind to events.
   add_buttonClick: function (handler) {
      ///<summary>Occures when a toolbar button is clicked.</summary>
      ///<value type="Function">A handler for the button click event.</value>
      ///<remarks>The signature for the handler should be:
      ///<code lang="JavaScript">function myHandler( sender, args ) { }</code>
      ///The <c>sender</c> parameter is a reference to the toolbar that fired the event. The <c>args</c> parameter is
      ///of type <see cref="T:J#Sys.EventArgs"/>. <c>args.command</c> is the name of the button that was clicked.
      ///Possible values are: <c>prev, next, zoomIn, zoomOut,pan, zoom1on1, zoomToWidth, zoomToPage, open, close, search, searchCancel</c>.
      ///Set <c>args.suppressDefault</c> to <c>false</c> to prevent the default action from executing. 
      ///</remarks>
      this.get_events().addHandler('buttonClick', handler);
   },
   remove_buttonClick: function (handler) {
      this.get_events().removeHandler('buttonClick', handler);
   },

   get_targetControlId: function () {
      ///<summary>Gets or sets the id of the PDF viewer control to target.</summary>
      ///<value type="String" mayBeNull="false">The id of the PDF viewer control to target</value>
      ///<remarks>Setting this value after the control has been initialized has no effect.</remarks>    
      return this._targetControlId;
   },

   set_targetControlId: function (value) {
      if (this._targetControlId != value) {
         this._targetControlId = value;
         this.raisePropertyChanged('targetControlId');
      }
   }
};

// Optional descriptor for JSON serialization.
TallComponents.PdfViewerToolbar.descriptor = {
    properties: [{ name: "targetControlId", type: String}]
};
// Register the class as a type that inherits from Sys.UI.Control.
TallComponents.PdfViewerToolbar.registerClass('TallComponents.PdfViewerToolbar', Sys.UI.Control);

if (typeof (Sys) !== 'undefined') { Sys.Application.notifyScriptLoaded(); }
